﻿#include "../../src/util/time_util.hh"
#include "../../src/util/timer_tree.hh"
#include "../framework/unittest.hh"
#include <iostream>
#include <stdlib.h>

FIXTURE_BEGIN(test_timer_tree)

class MyTask : public kratos::util::InterTimerNodeCallback {
public:
  MyTask(const std::string &name) { name_ = name; }
  virtual ~MyTask() {}
  // 通过 InterTimerNodeCallback 继承
  virtual bool do_task() override {
    count += 1;
    done = true;
    return true;
  }
  bool done{false};
  int count{0};
};

CASE(TestAddChildFront1) {
  kratos::util::InterTimerNode root_node(1, 100, "root");
  auto child1 = root_node.add_child_front(200, "child1");
  ASSERT_TRUE(child1);
  ASSERT_FALSE(root_node.add_child_front(0, "child1"));
}

CASE(TestAddChildEnd1) {
  kratos::util::InterTimerNode root_node(1, 100, "root");
  auto child1 = root_node.add_child_end(200, "child1");
  ASSERT_TRUE(child1);
  ASSERT_FALSE(root_node.add_child_end(0, "child1"));
}

CASE(TestAddTaskBack1) {
  kratos::util::InterTimerNode root_node(1, 100, "root");
  auto child1 = root_node.add_child_end(200, "child1");
  kratos::util::CbPtr task(new MyTask("task"));
  child1->add_task_back(task);
  auto start = kratos::util::get_os_time_millionsecond();
  while (true) {
    root_node.update(kratos::util::get_os_time_millionsecond());
    if (kratos::util::get_os_time_millionsecond() - start > 250) {
      break;
    }
  }
  ASSERT_TRUE(std::dynamic_pointer_cast<MyTask>(task)->done);
  ASSERT_TRUE(std::dynamic_pointer_cast<MyTask>(task)->count == 1);
}

CASE(TestAddTaskFront1) {
  kratos::util::InterTimerNode root_node(1, 100, "root");
  auto child1 = root_node.add_child_end(200, "child1");
  kratos::util::CbPtr task(new MyTask("task"));
  child1->add_task_front(task);
  auto start = kratos::util::get_os_time_millionsecond();
  while (true) {
    root_node.update_profile(kratos::util::get_os_time_millionsecond());
    if (kratos::util::get_os_time_millionsecond() - start > 250) {
      break;
    }
  }
  ASSERT_TRUE(std::dynamic_pointer_cast<MyTask>(task)->done);
  ASSERT_TRUE(std::dynamic_pointer_cast<MyTask>(task)->count == 1);
  std::stringstream ss;
  root_node.get_detail_report(ss);
  std::cout << ss.str() << std::endl;
}

FIXTURE_END(test_timer_tree)
